package com.homedo.microservice.open.service.gateway.manager.web.service;

import com.google.common.collect.Lists;
import com.homedo.common.bean.data.enums.ResponseEnum;
import com.homedo.common.bean.vo.context.UserContext;
import com.homedo.common.dao.bean.po.base.BasePo;
import com.homedo.common.exception.HomedoException;
import com.homedo.common.service.BaseService;
import com.homedo.common.util.Detect;
import com.homedo.microservice.open.service.gateway.manager.web.bean.po.DbSource;
import com.homedo.microservice.open.service.gateway.manager.web.bean.po.ServiceGateway;
import com.homedo.microservice.open.service.gateway.manager.web.bean.po.enhanced.ServiceGatewayEnhanced;
import com.homedo.microservice.open.service.gateway.manager.web.persistence.dao.DbSourceDao;
import com.homedo.microservice.open.service.gateway.manager.web.persistence.dao.ServiceGatewayDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @author 作者 jgshun
 * @date 创建时间 2018年09月25日 17时10分10秒
 */
@Service
public class ServiceGatewayService extends BaseService<ServiceGateway> {
    private static final Logger _LOGGER = LoggerFactory.getLogger(ServiceGatewayService.class);

    @Autowired
    private ServiceGatewayDao serviceGatewayDao;
    @Autowired
    private DbSourceDao dbSourceDao;


    @Override
    public List<ServiceGatewayEnhanced> getEnhanceds(List<?> ids, UserContext userContext) {
        List<ServiceGateway> serviceGateways = serviceGatewayDao.getListByIds(ids, ServiceGateway.class);

        if (!Detect.notEmpty(serviceGateways)) {
            return null;
        }

        return this.convent2Enhanceds(serviceGateways);
    }


    @Override
    public List<ServiceGatewayEnhanced> getEnhanceds4Active(List<?> ids, UserContext userContext) {
        List<ServiceGateway> serviceGateways = serviceGatewayDao.getListByIdsGreaterThanMark0(ids, ServiceGateway.class);

        if (!Detect.notEmpty(serviceGateways)) {
            return null;
        }

        return this.convent2Enhanceds(serviceGateways);
    }


    @Override
    public List<ServiceGatewayEnhanced> convent2Enhanceds(List<? extends BasePo> pos) {
        List<ServiceGateway> serviceGateways = (List<ServiceGateway>) pos;
        List<ServiceGatewayEnhanced> serviceGatewayEnhanceds = Lists.newArrayList();
        serviceGateways.forEach(e -> serviceGatewayEnhanceds.add(new ServiceGatewayEnhanced(e)));
        return serviceGatewayEnhanceds;
    }


    public List<ServiceGatewayEnhanced> getEnhancedsAll(UserContext userContext) {
        List<ServiceGateway> serviceGateways = serviceGatewayDao.getAllOrderBySort();

        if (!Detect.notEmpty(serviceGateways)) {
            return null;
        }

        return this.convent2Enhanceds(serviceGateways);
    }

    public List<ServiceGatewayEnhanced> getEnhancedsByName(String name, List<String> envs, UserContext userContext) {
        List<ServiceGateway> serviceGateways = serviceGatewayDao.getListByName(name, envs);

        if (!Detect.notEmpty(serviceGateways)) {
            return null;
        }

        return this.convent2Enhanceds(serviceGateways);
    }

    public ServiceGateway saveServiceGateway(ServiceGateway serviceGateway, DbSource dbSource, UserContext userContext) {
        if (!Detect.notEmpty(serviceGateway.getComment())) {
            List<ServiceGateway> serviceGateways = serviceGatewayDao.getListByName(serviceGateway.getName(), null);
            if (Detect.notEmpty(serviceGateways)) {
                serviceGateway.setComment(serviceGateways.get(0).getComment());//取出默认的中文名
            }
        }

        this.checkSave(serviceGateway, dbSource);

        serviceGateway.setCreateTime(new Date());
        serviceGateway.setUpdateTime(new Date());

        List<ServiceGateway> serviceGateways = serviceGatewayDao.getListByName(serviceGateway.getName(), Lists.newArrayList(serviceGateway.getEnv()));
        if (Detect.notEmpty(serviceGateways)) {
            _LOGGER.warn("[网关环境配置已存在:{}--{}]", serviceGateway.getName(), serviceGateway.getEnv());
            if (dbSource == null) {
                throw new HomedoException("[网关环境配置已存在]");
            }
            serviceGateway = serviceGateways.get(0);
        } else {
            serviceGateway = serviceGatewayDao.saveSelective(serviceGateway);
        }

        if (dbSource != null) {
            dbSource.setCreateTime(new Date());
            dbSource.setUpdateTime(new Date());
            List<DbSource> dbSources = dbSourceDao.getListByServiceGateway(dbSource.getServiceGatewayName(), Lists.newArrayList(dbSource.getEnv()));
            if (Detect.notEmpty(dbSources)) {
                _LOGGER.warn("[网关数据库配置已存在:{}--{}]", serviceGateway.getName(), serviceGateway.getEnv());
                throw new HomedoException("[网关数据库配置已存在]");
            }

            dbSourceDao.saveSelective(dbSource);
        }

        return serviceGateway;
    }

    private void checkSave(ServiceGateway serviceGateway, DbSource dbSource) {
        if (!Detect.notEmpty(serviceGateway.getName()) || !Detect.notEmpty(serviceGateway.getComment()) || !Detect.notEmpty(serviceGateway.getEnv())) {
            throw new HomedoException(ResponseEnum.PARAM_ERROR);
        }

        if (dbSource != null) {
            if (!Detect.notEmpty(dbSource.getServiceGatewayName()) || !Detect.notEmpty(dbSource.getEnv()) || !Detect.notEmpty(dbSource.getIp())
                    || !Detect.notEmpty(dbSource.getPort()) || !Detect.notEmpty(dbSource.getDbName())
                    || !Detect.notEmpty(dbSource.getUsername()) || !Detect.notEmpty(dbSource.getPassword()) || !Detect.isNumeric(dbSource.getPort())) {
                throw new HomedoException(ResponseEnum.PARAM_ERROR);
            }
        }
    }


    public void updateServiceGateway(String oldName, String newName, String newComment, UserContext userContext) {
        List<ServiceGateway> serviceGateways = serviceGatewayDao.getListByName(oldName, null);
        if (serviceGateways == null) {
            throw new HomedoException("[网关配置不存在]");
        }
        serviceGateways.forEach(e -> {
            e.setName(newName);
            e.setComment(newComment);
            e.setUpdateTime(new Date());

            serviceGatewayDao.updateByPrimaryKeySelective(e);
        });
        List<DbSource> dbSources = dbSourceDao.getListByServiceGateway(oldName, null);
        if (Detect.notEmpty(dbSources)) {
            dbSources.forEach(e -> {
                e.setServiceGatewayName(newName);
                e.setUpdateTime(new Date());

                dbSourceDao.updateByPrimaryKeySelective(e);
            });
        }
    }

    public void updateHystrixUrl(String name, String env, String hystrixUrl, UserContext userContext) {
        this.checkUpdateHystrixUrl(name, env, hystrixUrl);

        ServiceGateway serviceGateway = serviceGatewayDao.getListByName(name, Lists.newArrayList(env)).get(0);
        serviceGateway.setHystrixUrl(hystrixUrl);
        serviceGateway.setUpdateTime(new Date());

        serviceGatewayDao.updateByPrimaryKeySelective(serviceGateway);
    }

    public void deleteServiceGateway(String name, String env, UserContext userContext) {
        List<String> envs = Lists.newArrayList();
        if (Detect.notEmpty(env)) {
            envs.add(env);
        }

        List<ServiceGateway> serviceGateways = serviceGatewayDao.getListByName(name, envs);
        if (serviceGateways == null) {
            throw new HomedoException("[网关配置不存在]");
        }
        serviceGateways.forEach(e -> {
            serviceGatewayDao.deleteById(e.getId());
        });
        List<DbSource> dbSources = dbSourceDao.getListByServiceGateway(name, envs);
        if (Detect.notEmpty(dbSources)) {
            dbSources.forEach(e -> {
                dbSourceDao.deleteById(e.getId());
            });
        }
    }

    private void checkUpdateHystrixUrl(String name, String env, String hystrixUrl) {
        if (!Detect.notEmpty(name) || !Detect.notEmpty(env) || !Detect.notEmpty(hystrixUrl)) {
            throw new HomedoException(ResponseEnum.PARAM_ERROR);
        }
        String[] urls = hystrixUrl.split(",");

        for (String url : urls) {
            if (!url.startsWith("http://") && !url.startsWith("https://")) {
                throw new HomedoException(ResponseEnum.PARAM_ERROR);
            }
            String[] parts = url.split(":");
            if (parts.length != 3) {
                throw new HomedoException(ResponseEnum.PARAM_ERROR);
            }
            if (!Detect.isNumeric(parts[2])) {
                throw new HomedoException(ResponseEnum.PARAM_ERROR);
            }
        }
    }

}
